
#include "../../../inc/Ui/GoogleBuzz/Googlebuzzform.h"

using namespace Osp::Base;
using namespace Osp::Ui;
using namespace Osp::Ui::Controls;
#include "../../../inc/Utility/MyUtil.h"
int Googlebuzzform::FormId = -1;

Googlebuzzform::Googlebuzzform(void)
{
	clientID = L"306001726449-fc06vh80bfdq0ngehpbfi991p3b2f6t0.apps.googleusercontent.com";
	clientSecret = L"fCYq_66_lVZljsmdOdqgHiQC";
	redirectUri = L"urn:ietf:wg:oauth:2.0:oob";
	apiKey = L"AIzaSyDeX3wYvKbCQzJPIcrAF-Ytlj6dWeom5fA";
}

Googlebuzzform::~Googlebuzzform(void)
{
}

bool
Googlebuzzform::Initialize()
{
	Form::Construct(L"GoogleBuzzForm");

	return true;
}

result
Googlebuzzform::OnInitializing(void)
{
	result r = E_SUCCESS;

	// TODO: Add your initialization code here
	r = CreateWebControl();
	if (IsFailed(r)){
		AppLog("Cannot create web control");
		return r;
	}
	//GetAccessCode();
	return r;
}

result
Googlebuzzform::OnTerminating(void)
{
	result r = E_SUCCESS;

	// TODO: Add your termination code here

	return r;
}

result Googlebuzzform::CreateWebControl(void) {
	result r = E_SUCCESS;
	int screen_width = 0;
	int screen_height = 0;

	/*screen*/
	r = SystemInfo::GetValue("ScreenWidth", screen_width);
	TryCatch(r == E_SUCCESS, , "SystemInfo: To get a value is failed");

	r = SystemInfo::GetValue("ScreenHeight", screen_height);
	TryCatch(r == E_SUCCESS, , "SystemInfo: To get a value is failed");

	/*Web*/
	pWeb = new Web();
	r = pWeb->Construct(Rectangle(0, 0, screen_width, screen_height - 38));
	TryCatch(r == E_SUCCESS, ,"Web is not constructed\n ");

	r = this->AddControl(*pWeb);
	TryCatch(r == E_SUCCESS, ,"Web is not attached\n ");

	pWeb->SetFocus();

	return r;

	CATCH: AppLog("Error = %s\n", GetErrorMessage(r));
	return r;
}

void Googlebuzzform::GetAccessCode() {
	this->pWeb->SetLoadingListener(this);
	status = GET_TOKEN;
	String
			str =
					"https://accounts.google.com/o/oauth2/auth?client_id=306001726449-fc06vh80bfdq0ngehpbfi991p3b2f6t0.apps.googleusercontent.com&redirect_uri=urn:ietf:wg:oauth:2.0:oob&scope=https://www.googleapis.com/auth/buzz&response_type=code";
	this->pWeb->LoadUrl(str);

}

void Googlebuzzform::GetAccessToken() {

}

void Googlebuzzform::OnEstimatedProgress(int progress) {

}
void Googlebuzzform::OnHttpAuthenticationCanceled(void) {

}
bool Googlebuzzform::OnHttpAuthenticationRequestedN(
		const Osp::Base::String &host, const Osp::Base::String &realm,
		const Osp::Web::Controls::AuthenticationChallenge &authentication) {
	return false;
}
void Googlebuzzform::OnLoadingCanceled(void) {

}
void Googlebuzzform::OnLoadingCompleted(void) {

}
void Googlebuzzform::OnLoadingErrorOccurred(LoadingErrorType error,
		const Osp::Base::String &reason) {

}
bool Googlebuzzform::OnLoadingRequested(const Osp::Base::String &url,
		WebNavigationType type) {
	return false;
}
void Googlebuzzform::OnLoadingStarted(void) {

}
void Googlebuzzform::OnPageTitleReceived(const Osp::Base::String &title) {
	int index = 0;
	title.IndexOf("code", 0, index);
	if (index == -1)
		return;

	if (status == GET_TOKEN){
		title.SubString(index + 5, code);

		String url = L"https://accounts.google.com/o/oauth2/token";

		String body = L"";
		body.Append(L"client_id="); body.Append(clientID);
		body.Append(L"&client_secret="); body.Append(clientSecret);
		body.Append(L"&code="); body.Append(code);
		body.Append(L"&redirect_uri="); body.Append(redirectUri);
		body.Append(L"&grant_type="); body.Append(L"authorization_code");

		ByteBuffer *pBody = null;
		pBody = Utility::StringUtil::StringToUtf8N(body);

		//HttpHeader *pHeader = new HttpHeader();
		HttpHeader *pHeader = new HttpHeader();

		pHeader->AddField(String(L"Content-Type"), String(L"application/x-www-form-urlencoded"));
		//pHeader->AddField();

		Download(url, pBody, pHeader, NET_HTTP_METHOD_POST);
	}
	//pWeb->LoadUrl("file:///Res/index.html");
}
DecisionPolicy Googlebuzzform::OnWebDataReceived(const Osp::Base::String &mime,
		const Osp::Net::Http::HttpHeader &httpHeader) {

	return WEB_DECISION_CONTINUE;
}

void Googlebuzzform::OnTransactionAborted(HttpSession &httpSession,
		HttpTransaction &httpTransaction, result r) {

}
void Googlebuzzform::OnTransactionCertVerificationRequiredN(
		HttpSession &httpSession, HttpTransaction &httpTransaction,
		Osp::Base::String *pCert) {

}
void Googlebuzzform::OnTransactionCompleted(HttpSession &httpSession,
		HttpTransaction &httpTransaction) {

}
void Googlebuzzform::OnTransactionHeaderCompleted(HttpSession &httpSession,
		HttpTransaction &httpTransaction, int headerLen, bool bAuthRequired) {

}
void Googlebuzzform::OnTransactionReadyToRead(HttpSession &httpSession,
		HttpTransaction &httpTransaction, int availableBodyLen) {
	AppLog("Vao  on transaction ready to read");

	switch (status) {
		case GET_TOKEN:
			ProcessGetToken(httpSession, httpTransaction);
			break;

		case CREATE_ACTIVITY:
			ProcessCreateNewActivity(httpSession, httpTransaction);
			break;

		case SEARCH_ACTIVITIES:
			ProcessSearchActivity(httpSession, httpTransaction);
			break;

		default:
			break;
	}
	delete &httpTransaction;
	delete &httpSession;
}
void Googlebuzzform::OnTransactionReadyToWrite(HttpSession &httpSession,
		HttpTransaction &httpTransaction, int recommendedChunkSize) {

}

void Googlebuzzform::Download(String url, ByteBuffer *pBody,
		HttpHeader *pHeader, NetHttpMethod method) {
	result r = E_SUCCESS;


	HttpSession *pSession = new HttpSession();
	r = pSession->Construct(NET_HTTP_SESSION_MODE_NORMAL, null, url, null);

	if (IsFailed(r)) {
		AppLog("Googlebuzzform: That bai");
		return;
	}


	HttpTransaction *pTransaction = pSession->OpenTransactionN();
	if (pTransaction == null) {
		AppLog("Googlebuzzform: Can't open transaction");
		return;
	}

	pTransaction->AddHttpTransactionListener(*this);

	HttpRequest *pRequest = pTransaction->GetRequest();
	if (pRequest == null) {
		AppLog("Googlebuzzform: can't get request");
		return;
	}

	if (status == CREATE_ACTIVITY){
							AppLog("hix");
						}


	HttpHeader *pRequestHeader = pRequest->GetHeader();
	if (pHeader != null){
		IList *lstName = pHeader->GetFieldNamesN();
		int headerCount = lstName->GetCount();
		for (int i = 0; i < headerCount; i++){
			String *keyName = (String*)lstName->GetAt(i);
			IEnumerator *iEnum = pHeader->GetFieldValuesN(*keyName);
			iEnum->MoveNext();
			String *keyValue = (String*)iEnum->GetCurrent();
			pRequestHeader->AddField(*keyName, *keyValue);

		}
		delete lstName;
	}

	r = pRequest->SetUri(url);
	if (IsFailed(r)) {
		AppLog("Googlebuzzform: can't set url");
		return;
	}

	r = pRequest->SetMethod(method);
	if (IsFailed(r)) {
		AppLog("Googlebuzzform: can't set method");
		return;
	}

	if (pBody != null){
		int length = pBody->GetLimit() - 1;
		String lengthAsString = L"";
		lengthAsString.Append(length);
		pBody->SetPosition(0);
		pRequestHeader->AddField("Content-Length", lengthAsString);
		pTransaction->EnableTransactionReadyToWrite();
		pRequest->WriteBody(*pBody);
	}


	r = pTransaction->Submit();

	if (IsFailed(r)) {
		AppLog("Googlebuzzform: can't submit");

	}
//	delete pTransaction;
	if (pBody != null){
		delete pBody;
	}
	if (pHeader != null){
		delete pHeader;
	}
}

void Googlebuzzform::ProcessGetToken(HttpSession &httpSession, HttpTransaction &httpTransaction){
	HttpResponse* pResponse = httpTransaction.GetResponse();

	NetHttpStatusCode statusCode = pResponse->GetStatusCode();

	ByteBuffer* pBody = pResponse->ReadBodyN();
	int limit = pBody->GetLimit();
	pBody->Flip(POSITION_TO_ZERO);
	pBody->SetLimit(limit);

	if (statusCode != NET_HTTP_STATUS_OK) {
		AppLog("Failed");
	}



	JsonReader reader;
	JsonObject object;

	reader.read(pBody, object);
	JsonString *jsonString = null;
	jsonString = (JsonString*)object.getValueN(L"access_token");
	this->accessToken = jsonString->getValue();
	delete jsonString;
	jsonString = (JsonString*)object.getValueN(L"refresh_token");
	this->refreshToken = jsonString->getValue();
	delete jsonString;
	AppLog("Xong rùi");
	status = NONE;
	//delete pEncoder;
	delete pBody;
	//CreateNewActivity(L"Chao cac ban");
	pWeb->LoadUrl("file:///Res/index.html");
	SearchActivity();
}

void Googlebuzzform::CreateNewActivity(String content){
	String url = L"https://www.googleapis.com/buzz/v1/activities/@me/@self?key=AIzaSyDeX3wYvKbCQzJPIcrAF-Ytlj6dWeom5fA&alt=json&oauth_token=";
	url.Append(accessToken);
	HttpHeader *pHeader = new HttpHeader();

	pHeader->AddField(String(L"Content-Type"), String(L"application/json"));

	JsonObject data;

	JsonString jsonString;

	jsonString.setValue(L"note");

	data.insertValue(L"type", &jsonString);
	jsonString.setValue(content);
	data.insertValue(L"content", &jsonString);

	JsonObject object;
	object.insertValue(L"object", &data);

	float longitude = 0;
	float latitude = 0;
	CurrentLocationService::getInstance()->GetCurrentLocation(longitude, latitude);
	String temp = L"";
	temp.Append(latitude);
	temp.Append(' ');
	temp.Append(longitude);
	jsonString.setValue(temp);
	object.insertValue(L"geocode", &jsonString);
	JsonObject objectData;
	objectData.insertValue(L"data", &object);

	String strJsonString = objectData.toJsonString();


	ByteBuffer *pBody = null;
	pBody = Utility::StringUtil::StringToUtf8N(strJsonString);
	status = CREATE_ACTIVITY;
	Download(url, pBody, pHeader, NET_HTTP_METHOD_POST);
}

void Googlebuzzform::ProcessCreateNewActivity(HttpSession &httpSession, HttpTransaction &httpTransaction){
	HttpResponse* pResponse = httpTransaction.GetResponse();

	NetHttpStatusCode statusCode = pResponse->GetStatusCode();

	ByteBuffer* pBody = pResponse->ReadBodyN();
	int limit = pBody->GetLimit();
	pBody->Flip(POSITION_TO_ZERO);
	pBody->SetLimit(limit);

	if (statusCode != 200) {
		AppLog("Failed");
	}


	JsonReader reader;
	try{
		JsonObject object;
		reader.read(pBody, object);
		AppLog("He he");
	}catch (JsonException ex){
		AppLog("hix: %S at %d", ex.getMessage().GetPointer(), ex.getWhere());
	}

}

void Googlebuzzform::SearchActivity(){
	status = SEARCH_ACTIVITIES;
	String url = L"https://www.googleapis.com/buzz/v1/activities/search?key=";
	url.Append(apiKey);
	float latitude = 0;
	float longitude = 0;
	CurrentLocationService *locationService = CurrentLocationService::getInstance();
	locationService->GetCurrentLocation(longitude, latitude);
	url.Append(L"&lat="); url.Append(latitude);
	url.Append(L"&lon="); url.Append(longitude);
	url.Append(L"&radius=100000&alt=json");
	//String url = L"https://www.googleapis.com/buzz/v1/activities/@all/@public";
	HttpHeader *pHeader = new HttpHeader();

	pHeader->AddField(String(L"Content-Type"), String(L"application/json"));
	Download(url, null, pHeader, NET_HTTP_METHOD_GET);
}

void test(ByteBuffer *buffer){

}

void Googlebuzzform::ProcessSearchActivity(HttpSession &httpSession, HttpTransaction &httpTransaction){
	HttpResponse* pResponse = httpTransaction.GetResponse();

	NetHttpStatusCode statusCode = pResponse->GetStatusCode();

	ByteBuffer* pBody = pResponse->ReadBodyN();
	int limit = pBody->GetLimit();
	pBody->Flip(POSITION_TO_ZERO);
	pBody->SetLimit(limit);

	if (statusCode != 200) {
		AppLog("Failed");
	}

	pBody->SetPosition(0);

	JsonObject jsonObject;

	JsonReader reader;
	reader.read(pBody, jsonObject);

	JsonObject *dataJsonObject = null;
	dataJsonObject = (JsonObject*) jsonObject.getValueN(L"data");
	JsonArray *itemsJsonArray = null;
	itemsJsonArray = (JsonArray*) dataJsonObject->getValueN(L"items");
	delete dataJsonObject;
	int count = itemsJsonArray->getSize();

	JsonObject *actorJsonObject = null;
	JsonString *actorPictureJsonString = null;
	JsonString *titleJsonString = null;
	JsonString *actorNameJsonString = null;
	JsonString *addressJsonString = null;
	JsonString *placeNameJsonString = null;
	JsonString *actorPositionJsonString = null;

	String latlngString = L"";
	String utf8PlaceNameString = L"";
	String utf8AddressString = L"";
	String utf8TitleString = L"";

	for (int i = 0; i < count; i++){
		JsonObject *element = null;
		element = (JsonObject*)itemsJsonArray->getValueN(i);

		titleJsonString = (JsonString*)element->getValueN(L"title");


		actorJsonObject = (JsonObject*)element->getValueN(L"actor");

		actorPictureJsonString = (JsonString*)actorJsonObject->getValueN(L"thumbnailUrl");
		actorNameJsonString = (JsonString*)actorJsonObject->getValueN(L"name");

		addressJsonString = (JsonString*)element->getValueN(L"address");
		placeNameJsonString = (JsonString*)element->getValueN(L"placeName");

		actorPositionJsonString = (JsonString*)element->getValueN(L"geocode");


		latlngString = actorPositionJsonString->getValue();

		float latFloat = Float::GetMinValue();
		float lngFloat = Float::GetMinValue();
		int spaceIndexInt = 0;
		latlngString.IndexOf(' ', 0, spaceIndexInt);
		if (spaceIndexInt != -1){
			String lngString = L"";
			latlngString.SubString(spaceIndexInt, lngString);
			latlngString.Replace(lngString, L"");
			lngString.Trim();
			Float::Parse(lngString, lngFloat);
			Float::Parse(latlngString, latFloat);
		}

		if (placeNameJsonString == null){
			placeNameJsonString = new JsonString();
		}
		if (addressJsonString == null){
			addressJsonString = new JsonString();
		}



		WebController::SetGoogleBuzzMarker(latFloat, lngFloat, actorNameJsonString->getValue(), actorPictureJsonString->getValue(),
				placeNameJsonString->getValue(), addressJsonString->getValue(), titleJsonString->getValue());



		delete actorNameJsonString;
		delete placeNameJsonString;
		delete addressJsonString;
		delete titleJsonString;
		delete actorPictureJsonString;
		delete actorPositionJsonString;
		delete actorJsonObject;
		delete element;
	}

	FormManager *pFormManager = null;
	FormManager::GetInstance(pFormManager);
	pFormManager->SetCurrentForm(WebForm::GetFormId());

	AppLog("Xong rui");
	status = NONE;
}

void Googlebuzzform::LocationUpdate(float latitude, float longitude){

}
